package com.pkk.cloud.support.admin.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pkk.cloud.support.admin.dto.req.urls.OauthResourceUrlCheckReqDto;
import com.pkk.cloud.support.admin.dto.req.urls.OauthUrlsAddReqDto;
import com.pkk.cloud.support.admin.dto.req.urls.ResourceUrlBindReqData;
import com.pkk.cloud.support.admin.dto.resp.resources.OauthResourceSimpleRespDto;
import com.pkk.cloud.support.admin.dto.resp.urls.OauthResourceUrlsCheckRespDto;
import com.pkk.cloud.support.admin.dto.resp.urls.OauthUrlsAddRespDto;
import com.pkk.cloud.support.admin.dto.resp.urls.OauthUrlsAllRespDto;
import com.pkk.cloud.support.admin.entity.resource.PenguinSysUrl;
import com.pkk.cloud.support.admin.entity.resource.PenguinSysUrlResource;
import com.pkk.cloud.support.admin.exception.code.OauthAdminBusinessCode;
import com.pkk.cloud.support.admin.mybatis.resource.PenguinSysUrlMapper;
import com.pkk.cloud.support.admin.service.PenguinSysResourceService;
import com.pkk.cloud.support.admin.service.PenguinSysUrlResourceService;
import com.pkk.cloud.support.admin.service.PenguinSysUrlService;
import com.pkk.components.exceptions.BusinessException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PenguinSysUrlServiceImpl extends ServiceImpl<PenguinSysUrlMapper, PenguinSysUrl> implements
    PenguinSysUrlService {

  @Resource
  private PenguinSysUrlMapper penguinSysUrlMapper;
  @Resource
  private PenguinSysUrlResourceService penguinSysUrlResourceService;
  @Resource
  private PenguinSysResourceService penguinSysResourceService;

  /**
   * @Description: 保存接口信息
   * @Param: record
   * @return: int
   * @Author: peikunkun
   * @Date: 2020/4/11 0011 下午 5:09
   */
  @Override
  public boolean insertPenguinSysUrl(PenguinSysUrl record) {
    return penguinSysUrlMapper.insertPenguinSysUrl(record) == 1;
  }

  @Override
  public PenguinSysUrl selectByPrimaryKey(Long id) {
    return penguinSysUrlMapper.selectByPrimaryKey(id);
  }

  @Override
  public int updateByPrimaryKeySelective(PenguinSysUrl record) {
    return penguinSysUrlMapper.updateByPrimaryKeySelective(record);
  }

  /**
   * @Description:根据用户id获取资源地址
   * @Param: parseLong
   * @return: java.util.List<java.lang.String>
   * @Author: peikunkun
   * @Date: 2020/3/18 下午9:10
   */
  @Override
  public List<String> findUserUrlResourceByUserId(long userId) {
    //系统资源的关系表
    List<PenguinSysUrl> penguinSysUrlResources = this.findPenguinUserUrlResourceByUserId(userId);
    return penguinSysUrlResources.stream().map(PenguinSysUrl::getUrl).collect(Collectors.toList());
  }


  /**
   * @Description: 获取资源信息依据用户id
   * @Param: userId
   * @return: java.util.List<com.pkk.cloud.support.admin.entity.resource.PenguinSysUrlResource>
   * @Author: peikunkun
   * @Date: 2020/3/18 下午9:13
   */
  @Override
  public List<PenguinSysUrl> findPenguinUserUrlResourceByUserId(long userId) {
    return penguinSysUrlMapper.findPenguinUserUrlResourceByUserId(userId);
  }

  /**
   * @Description: 保存接口
   * @Param: urls
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 下午 3:15
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public OauthUrlsAddRespDto saveSysUrl(OauthUrlsAddReqDto reqDto, String userId) {
    //响应结果
    Set<String> exists = new HashSet<>();
    Set<String> fails = new HashSet<>();

    //客户端资源信息
    final OauthResourceSimpleRespDto resource = penguinSysResourceService.getResourceById(reqDto.getResourceId());
    if (null == resource) {
      throw new BusinessException(OauthAdminBusinessCode.CLIENT_NOT_EXISTS);
    }

    //获取接口所属客户端信息
    Set<String> clientUrls = this.findClientUrlsByClientId(resource.getOwnClientId());

    final Long resourceId = reqDto.getResourceId();
    reqDto.getUrls().stream().forEach(urls -> {
      try {
        if (clientUrls.contains(urls.getUrl())) {
          exists.add(urls.getUrl());
          return;
        }

        //保存和绑定操作
        final PenguinSysUrl penguinSysUrl = new PenguinSysUrl();
        BeanUtils.copyProperties(urls, penguinSysUrl);
        penguinSysUrl.setCreateTime(new Date());
        penguinSysUrl.setCreateName(userId);
        penguinSysUrl.setOwnClientId(resource.getOwnClientId());
        this.insertPenguinSysUrl(penguinSysUrl);
        penguinSysUrlResourceService.insertSysUrlResource(
            PenguinSysUrlResource.builder().resourceId(resourceId).urlId(penguinSysUrl.getId()).build());
      } catch (Exception e) {
        fails.add(urls.getUrl());
        return;
      }
    });
    return new OauthUrlsAddRespDto(exists, fails);
  }

  /**
   * @Description: 删除系统接口依据id
   * @Param: id
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 下午 3:40
   */
  @Override
  public boolean delSysUrlById(Long[] ids) {
    for (int i = 0; i < ids.length; i++) {
      penguinSysUrlMapper.updateById(PenguinSysUrl.builder().isDeleted(true).id(ids[i]).updateTime(new Date()).build());
    }
    return true;
  }

  /**
   * @Description: 更新接口地址依据id
   * @Param: url
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 下午 3:48
   */
  @Override
  public boolean updateSysUrlById(PenguinSysUrl url) {
    return penguinSysUrlMapper.updateById(url) == 1;
  }

  /**
   * @Description: 获取系统全部接口
   * @return: java.util.List<com.pkk.cloud.support.admin.dto.resp.urls.OauthUrlsAllReqDto>
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 下午 3:54
   */
  @Override
  public List<OauthUrlsAllRespDto> findSysUrlList() {
    return penguinSysUrlMapper.findSysUrlList();
  }

  /**
   * @Description: 根据按钮id资源查询所拥有的接口信息
   * @Param: body
   * @return: java.util.List<com.pkk.cloud.support.admin.dto.resp.urls.OauthUrlsAllReqDto>
   * @Author: peikunkun
   * @Date: 2020/4/11 0011 下午 3:10
   */
  @Override
  public List<OauthUrlsAllRespDto> findUrlsByResourceId(Long resourceId) {
    return penguinSysUrlMapper.findUrlsByResourceId(resourceId);
  }

  /**
   * @Description: 获取已绑定接口信息依据按钮和菜单信息
   * @Param: buttonId
   * @Param resourceId
   * @return: java.util.List<java.lang.Long>
   * @Author: peikunkun
   * @Date: 2020/4/22 0022 上午 10:34
   */
  @Override
  public Set<Long> getExistsUrlIdByResourceInfo(Long buttonId, Long resourceId) {
    final HashMap<String, Object> condition = new HashMap<>(3);
    condition.put("buttonId", buttonId);
    condition.put("resourceId", resourceId);
    return penguinSysUrlMapper.getExistsUrlIdByResourceInfo(condition);
  }

  /**
   * @Description: 获取客户端下面的所有接口
   * @Param: ownClientId
   * @return: java.util.Set<java.lang.String>
   * @Author: peikunkun
   * @Date: 2020/4/22 0022 上午 11:50
   */
  @Override
  public Set<String> findClientUrlsByClientId(Long ownClientId) {
    return penguinSysUrlMapper.findClientUrlsByClientId(ownClientId);
  }

  /**
   * @Description: 获取资源接口列表
   * @Param: request
   * @Author: peikunkun
   * @Date: 2020/4/22 0022 上午 10:24
   */
  @Override
  public List<OauthResourceUrlsCheckRespDto> getResourceBindUrlList(OauthResourceUrlCheckReqDto body) {
    List<OauthUrlsAllRespDto> urlResourceAll = this.findUrlsByResourceId(body.getResourceId());
    Set<Long> urlResourceExists = this.getExistsUrlIdByResourceInfo(body.getButtonId(), body.getResourceId());
    return iteratorUrlResource(urlResourceAll, urlResourceExists);
  }

  /**
   * @Description: 处理接口资源
   * @Param: [urlResourceForEditRespData, urlResourceExists]
   * @return: java.util.List<com.quzeng.common.admin.response.urlresource.UrlResourceForEditRespData>
   * @Author: peikunkun
   * @Date: 2020/4/22 0022 上午 10:24
   */
  private static List<OauthResourceUrlsCheckRespDto> iteratorUrlResource(
      List<OauthUrlsAllRespDto> urlResourceAll, Set<Long> urlResourceExists) {
    final ArrayList<OauthResourceUrlsCheckRespDto> oauthResourceUrlsCheckRespDtos = new ArrayList<>();
    urlResourceAll.stream().forEach(url -> {
      oauthResourceUrlsCheckRespDtos.add(
          OauthResourceUrlsCheckRespDto.builder().id(url.getId()).url(url.getUrl()).urlName(url.getUrlName())
              .check(urlResourceExists.contains(url.getId())).build());
    });
    return oauthResourceUrlsCheckRespDtos;
  }

  /**
   * @Description: 绑定资源与接口信息
   * @Param: body
   * @return: java.lang.Boolean
   * @Author: peikunkun
   * @Date: 2020/4/22 0022 下午 3:09
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean bindResourceUrl(ResourceUrlBindReqData body) {
    penguinSysUrlResourceService.delSysUrlByResourceId(body.getResourceId());
    if (body.getUrls().length > 0) {
      penguinSysUrlResourceService.batchSaveSysResourceUrl(body.getResourceId(), body.getUrls());
    }
    return true;
  }

}
